package com.kdgc.energy.dmm.time;

import cn.hutool.core.util.StrUtil;
import lombok.Setter;

import java.util.LinkedHashMap;
import java.util.Map;

/**
 * 耗时统计器
 *
 * @author xu.wenchang
 * @version 1.0 2022/04/21
 */
public class TimeStatistical {
    private String name;
    private long startTime;
    private long endTime;
    Map<String, Phase> phases;
    private int unclosed = 0;
    
    public TimeStatistical() {
        startTime = System.currentTimeMillis();
    }
    
    public void setName(String name) {
        this.name = name;
    }
    
    public String getName() {
        return this.name;
    }
    
    public long total() {
        return this.endTime - this.startTime;
    }
    
    public void end() {
        endTime = System.currentTimeMillis();
    }
    
    public void phaseStart(String phaseName) {
        if (null == phases) {
            phases = new LinkedHashMap<>();
        }
        
        if (!phases.containsKey(phaseName)) {
            phases.put(phaseName, new Phase(phaseName));
        }
    }
    
    public void phaseEnd(String phaseName) {
        phases.computeIfPresent(phaseName, (k, v) -> {
            TimeStatistical.this.unclosed--;
            v.endTime = System.currentTimeMillis();
            return v;
        });
    }
    
    public String statisticalInfo() {
        final StringBuilder builder = new StringBuilder();
        builder.append("-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-");
        builder.append(System.lineSeparator());
        
        builder.append(this.name);
        builder.append(System.lineSeparator());
        builder.append("总耗时:");
        builder.append(endTime - startTime);
        builder.append(" 毫秒.");
        builder.append(System.lineSeparator());
        
        long last = 0;
        long first = 0;
        
        for (Phase phase : this.phases.values()) {
            builder.append(phase.name);
            builder.append(" 耗时: ");
            builder.append(phase.endTime - phase.startTime);
            builder.append(" 毫秒.");
            builder.append(System.lineSeparator());
            last = phase.endTime;
            
            if (first == 0) {
                first = phase.startTime;
            }
        }
        
        long other = (first - startTime) + (endTime - last);
        
        if (other > 0) {
            builder.append("[other]");
            builder.append(" 耗时: ");
            builder.append(other);
            builder.append(" 毫秒.");
        }
        
        builder.append(System.lineSeparator());
        builder.append("-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-");
        builder.append(System.lineSeparator());
        TimeAnalyser.INST.addExecuteRecord(this);
        return builder.toString();
    }
    
    @Setter
    class Phase {
        String name;
        long startTime;
        long endTime;
        
        Phase(String name) {
            this.name = StrUtil.repeat(" ", TimeStatistical.this.unclosed * 4) + "[" + name + "]";
            this.startTime = System.currentTimeMillis();
            TimeStatistical.this.unclosed++;
        }
    }
}
